﻿#include <QFileInfo>
#include <QCoreApplication>
#include <QDateTime>
#include <QDir>
#include <QTextStream>
#include <QDebug>
#include "Public.h"
#include "CLogMng.h"

QVector<QSharedPointer<LogData>> getRecentHistoryLogs(const QString& moduleName, const QString& deviceName, int maxCount)
{
	QVector<QSharedPointer<LogData>> recentLogs;

	if (maxCount <= 0) 
	{
		return recentLogs;
	}

	// 只读取最近1天的日志文件
	QVector<QString> logFiles = getRecentLogFiles(moduleName, deviceName, 1);

	if (logFiles.isEmpty()) 
	{
		return recentLogs;
	}

	// 从最新的文件开始读取
	for (const QString& filePath : logFiles) 
	{
		if (recentLogs.size() >= maxCount) 
		{
			break;
		}

		int remaining = maxCount - recentLogs.size();
		QVector<QSharedPointer<LogData>> fileLogs = readRecentLogsFromFile(filePath, moduleName, deviceName, remaining);

		// 新文件的日志添加到前面（保持时间顺序）
		recentLogs = fileLogs + recentLogs;
	}

	// 确保不超过最大数量
	if (recentLogs.size() > maxCount) 
	{
		recentLogs = recentLogs.mid(recentLogs.size() - maxCount);
	}
	return recentLogs;
}

extern QVector<QString> getRecentLogFiles(const QString& moduleName, const QString& deviceName, int days /*= 3*/)
{
	QVector<QString> logFiles;
	QString appDir = QCoreApplication::applicationDirPath();
	QDateTime current = QDateTime::currentDateTime();
	// 获取最近days天的日志文件（从今天往前）
	for (int i = 0; i < days; ++i) 
	{
		QDateTime date = current.addDays(-i);
		QString year = date.toString("yyyy");
		QString month = date.toString("yyyyMM");
		QString dayStr = date.toString("yyyyMMdd");

		// 构建日志目录路径
		QString logDir = QString("%1/Log/%2/%3/%4/%5/")
			.arg(appDir)
			.arg(moduleName)
			.arg(deviceName)
			.arg(year)
			.arg(month);

		// 构建日志文件名
		QString fileName = QString("%1%2.log").arg(deviceName).arg(dayStr);
		QString filePath = QDir(logDir).absoluteFilePath(fileName);

		if (QFile::exists(filePath))
		{
			logFiles.append(filePath);
		}
	}

	return logFiles;
}

extern QVector<QSharedPointer<LogData>> readRecentLogsFromFile(const QString& filePath, const QString& moduleName, const QString& deviceName, int maxCount)
{
	QVector<QSharedPointer<LogData>> logs;

	QFile file(filePath);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
	{
		return logs;
	}

	// 方法1：从文件末尾开始读取（效率更高）
	if (file.size() > 1024 * 1024)
	{ // 文件大于1MB时使用优化方法
		logs = readFromFileEnd(file, filePath, moduleName, deviceName, maxCount);
	}
	else
	{
		// 方法2：小文件直接全部读取
		logs = readEntireFile(file, filePath, moduleName, deviceName, maxCount);
	}

	file.close();
	return logs;
}

extern QSharedPointer<LogData> parseLogLine(const QString& line, const QString& moduleName, const QString& deviceName)
{
	if (line.isEmpty())
	{
		return nullptr;
	}

	// 使用正则表达式匹配中括号内容
	QRegExp regex("\\[([^\\]]*)\\]"); // 改进正则，匹配非]字符
	int pos = 0;
	QStringList parts;

	while ((pos = regex.indexIn(line, pos)) != -1)
	{
		QString captured = regex.cap(1).trimmed();
		if (!captured.isEmpty())
		{
			parts.append(captured);
		}
		pos += regex.matchedLength();

		// 安全限制，避免无限循环
		if (parts.size() >= 10) 
		{
			break;
		}
	}

	if (parts.size() < 4)
	{
		qDebug() << "Invalid log line format, expected 4 parts but got" << parts.size() << ":" << line;
		return nullptr;
	}

	QString levelStr = parts[0];
	QString timestamp = parts[1];
	QString funcName = parts[2];
	QString logContent = parts[3];

	// 根据级别字符串获取级别枚举值
	int level = getLevelFromString(levelStr);

	// 创建日志数据对象 - 根据实际的LogData构造函数调整参数顺序
	return QSharedPointer<LogData>::create(level, levelStr, timestamp, moduleName, deviceName, funcName, logContent);
}

QVector<QSharedPointer<LogData>> readFromFileEnd(QFile& file, const QString& filePath, const QString& moduleName, const QString& deviceName, int maxCount)
{
	QVector<QSharedPointer<LogData>> logs;
	const qint64 bufferSize = 8192; // 8KB缓冲区
	qint64 fileSize = file.size();
	qint64 pos = qMax(fileSize - bufferSize, qint64(0));

	QVector<QString> lines;
	int collectedLines = 0;

	// 从文件末尾向前读取，直到收集到足够的行数或到达文件开头
	while (pos >= 0 && collectedLines < maxCount + 10) 
	{
		file.seek(pos);
		QTextStream stream(&file);
		stream.setCodec("UTF-8");

		// 读取当前缓冲区的内容
		QString content = stream.readAll();
		QStringList newLines = content.split('\n');

		// 反转顺序，因为是从后往前读
		for (auto it = newLines.rbegin(); it != newLines.rend(); ++it) 
		{
			QString line = it->trimmed();
			if (!line.isEmpty()) 
			{
				lines.prepend(line);
				collectedLines++;
			}
		}

		// 如果已经收集到足够多的行或者到达文件开头，就停止
		if (pos == 0 || collectedLines >= maxCount + 10) 
		{
			break;
		}
		// 向前移动一个缓冲区
		pos = qMax(pos - bufferSize, qint64(0));
	}

	// 解析日志行（从最新的开始，即lines的末尾）
	int count = 0;
	for (auto it = lines.rbegin(); it != lines.rend() && count < maxCount; ++it) 
	{
		QSharedPointer<LogData> logData = parseLogLine(*it, moduleName, deviceName);
		if (logData) {
			logs.append(logData);
			count++;
		}
	}

	return logs;
}

QVector<QSharedPointer<LogData>> readEntireFile(QFile& file, const QString& filePath, const QString& moduleName, const QString& deviceName, int maxCount)
{
	QVector<QSharedPointer<LogData>> logs;

	QTextStream stream(&file);
	stream.setCodec("UTF-8");

	// 读取所有行
	QStringList allLines;
	while (!stream.atEnd())
	{
		allLines.append(stream.readLine());
	}

	// 从文件末尾开始解析（最新的日志在文件末尾）
	int count = 0;
	for (auto it = allLines.rbegin(); it != allLines.rend() && count < maxCount; ++it) 
	{
		QString line = it->trimmed();
		if (line.isEmpty()) 
		{
			continue;
		}

		QSharedPointer<LogData> logData = parseLogLine(line, moduleName, deviceName);
		if (logData) {
			logs.append(logData);
			count++;
		}
	}

	return logs;
}

int getLevelFromString(const QString& levelStr)
{
	int nLevel = 0;
	for (auto itor = CLogMng::instance().m_mapLogLevelConfigs.begin(); itor != CLogMng::instance().m_mapLogLevelConfigs.end(); itor++)
	{
		SLogLevelConfig config = itor.value();
		if (config.desc == levelStr)
		{
			nLevel = config.id;
			break;
		}
	}
	return nLevel;
}
